package top.jolyoulu.corecommon.utils.encryption;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @Author: JolyouLu
 * @Date: 2023/3/18 20:42
 * @Description
 */
@Slf4j
public class AESUtils {

    /**
     * AES 加密算法
     * @param input 原文
     * @param key 密钥（必须16个字节）
     * @return
     * @throws Exception
     */
    public static String encrypt(String input, String key)  {
        return encrypt(input.getBytes(),key);
    }

    /**
     * AES 解密算法
     * @param input 密文
     * @param key 密钥（必须16个字节）
     * @return
     * @throws Exception
     */
    public static String decrypt(String input, String key) {
        return decrypt(input.getBytes(),key);
    }

    /**
     * AES 加密算法
     * @param input 原文
     * @param key 密钥（必须16个字节）
     * @return
     * @throws Exception
     */
    public static String encrypt(byte[] input, String key)  {
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //创建加密规则 参数1：密钥的字节 参数2：加密类型
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            //进行加密初始化 参数1：选择模式，加密模式/解密模式 参数2：加密规则
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
            //传入原文字节数值，调用加密方法
            byte[] bytes = cipher.doFinal(input);
            return Base64Utils.urlEncode(bytes);
        } catch (NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException |
                 InvalidKeyException e) {
            log.error("encrypt",e);
        }
        return null;
    }

    /**
     * AES 解密算法
     * @param input 密文
     * @param key 密钥（必须16个字节）
     * @return
     * @throws Exception
     */
    public static String decrypt(byte[] input, String key) {
        byte[] deBase64 = Base64Utils.urlDecode(input);
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //创建解密规则 参数1：密钥的字节 参数2：加密类型
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            //进行解密初始化 参数1：选择模式，加密模式/解密模式 参数2：加密规则
            cipher.init(Cipher.DECRYPT_MODE,secretKeySpec);
            //传入密文字节数值，调用解密方法
            byte[] bytes = cipher.doFinal(deBase64);
            return new String(bytes);
        } catch (NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException |
                 InvalidKeyException e) {
            log.error("decrypt",e);
        }
        return null;
    }

    public static void main(String[] args){
        //原文
        String input = "key=1&value=4&";
        //定义密钥（使用AES加密，密钥必须是16字节）
        String key = "8e1291fd6f3d4dde95a7a24819dce1d1";
        System.out.println("<======加密======>");
        String encryptAES = encrypt(input, key);
        System.out.println(encryptAES);
        System.out.println("<======解密======>");
        String decryptAES = decrypt("_Z9cZkVU_DBT23jHSzUtQDkU4nX_I65iWVqMIlvIzsAh_sFnsAUbBN8LsDAvng1X", key);
        System.out.println(decryptAES);
    }

}
